package com.group3.service.impl;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.group3.dao.*;
import com.group3.domain.*;
import com.group3.exception.BusinessException;
import com.group3.exception.ExceptionEnum;
import com.group3.pojo.Page;
import com.group3.pojo.receive.LeaveReceive;
import com.group3.service.StudentLeaveService;
import com.group3.utils.JWTUtils;
import com.group3.utils.NotNull;
import com.group3.utils.Result;
import com.group3.utils.ResultUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * LeaveServiceImpl
 *
 * @author WenhaoChen
 * 2021/06/10 16:57
 **/
@Service
public class StudentLeaveServiceImpl implements StudentLeaveService {
    @Resource
    private LeaveMapper leaveMapper;
    @Resource
    private FileMapper fileMapper;
    @Resource
    private LeaveDetailMapper detailMapper;
    @Resource
    private LeaveOperationRecordMapper recordMapper;

    /**
     * @description: getLeaveRecord
     * @param: [studentId, page]
     * @return: [java.lang.String, com.group3.pojo.Page]
     * @author WenhaoChen
     * @date: 2021/6/11 23:32
     */
    @Override
    public Result<List<Leave>> getLeaveRecord(LeaveReceive leaveReceive) {
        LeaveExample leaveExample = new LeaveExample();
        LeaveExample.Criteria criteria = leaveExample.createCriteria();
                criteria.andStudentIdEqualTo(leaveReceive.getStudentId());//根据学生id获取请假数据

        if (NotNull.judge(leaveReceive.getTheme())) {//传入了请假主题
            criteria.andThemeLike("%"+(leaveReceive.getTheme())+"%");//增加查询条件
        }
        if (NotNull.judge(leaveReceive.getStartTime())) {//传入了提交时间
            criteria.andSubmitTimeGreaterThanOrEqualTo(leaveReceive.getStartTime());
        }
        if (NotNull.judge(leaveReceive.getEndTime())) {//传入了提交时间
            criteria.andSubmitTimeLessThanOrEqualTo(leaveReceive.getEndTime());
        }
        if (NotNull.judge(leaveReceive.getType())) {//传入了请假原因（请假类型）
            criteria.andTypeEqualTo(leaveReceive.getType());//增加查询条件
        }
        if (NotNull.judge(leaveReceive.getState())) {//传入了审批状态
            criteria.andStateEqualTo(leaveReceive.getState());//增加查询条件
        }

        PageHelper.startPage(leaveReceive.getPageNumber(), leaveReceive.getPageSize());//启动分页
        List<Leave> leaves = leaveMapper.selectByExample(leaveExample);
        PageInfo<Leave> leavePageInfo = new PageInfo<>(leaves);//获取分页信息
        return ResultUtil.success(leaves, leavePageInfo.getTotal());
    }

    /**
     * @description: getLeaveDetail
     * @param: [leaveId]
     * @return: [java.lang.String]
     * @author: WenhaoChen
     * @date: 2021/6/11 23:32
     */
    @Override
    public Result getLeaveDetail(String leaveId) {
        int lid = Integer.parseInt(leaveId);//leaveId转为int型

        LeaveDetailExample detailExample = new LeaveDetailExample();
        detailExample
                .createCriteria()
                .andLeaveIdEqualTo(lid);

        List<LeaveDetail> leaveDetail = detailMapper.selectByExample(detailExample);
        LeaveOperationRecordExample recordExample = new LeaveOperationRecordExample();
        recordExample
                .createCriteria()
                .andLeaveIdEqualTo(lid);
        List<LeaveOperationRecord> records = recordMapper.selectByExample(recordExample);
        FileExample fileExample = new FileExample();
        fileExample
                .createCriteria()
                .andOriginIdEqualTo(2)
                .andOriginIdEqualTo(lid);
        List<File> files = fileMapper.selectByExample(fileExample);//获取该请假详情的附件

        Map<String, Object> map = new HashMap<>();
        map.put("leaveDetail", leaveDetail);
        map.put("files", files);
        map.put("operationRecords", records);//请假操作记录

        return ResultUtil.success(map, 1);//这类查询详情也应该这样返回吗？
    }

    /**
     * @description: submitLeave
     * @param: [studentId, leave]
     * @return: [java.lang.String, com.group3.domain.Leave]
     * @author: WenhaoChen
     * @date: 2021/6/12 0:00
     */
    @Override
    @Transactional
    public Result submitLeave(Leave leave,String token) {
        DecodedJWT jwt = JWTUtils.getToken(token);//获取token
        String studentId = jwt.getClaim("id").asString();//获取登录学生的id

        leave.setStudentId(studentId);
        leave.setSubmitTime(new Date());
        int result = leaveMapper.insertSelective(leave);
        if (result > 0) {
            LeaveOperationRecord record = new LeaveOperationRecord();
            record.setLeaveId(leave.getLeaveId());
            record.setOperationTime(leave.getSubmitTime());
            record.setReasonsFailure("提交申请");
            int re = recordMapper.insertSelective(record);
            if (re > 0) {
                return ResultUtil.success();
            } else {
                throw new BusinessException(ExceptionEnum.ERROR);
            }
        } else {
            throw new BusinessException(ExceptionEnum.ERROR);
        }
    }

    /**
     * @description: redoLeave
     * @param: [leave]
     * @return: [com.group3.domain.Leave]
     * @author: WenhaoChen
     * @date: 2021/6/12 13:55
     */
    @Override
    @Transactional
    public Result redoLeave(Leave leave,String token) {
        DecodedJWT jwt = JWTUtils.getToken(token);//获取token
        String studentId = jwt.getClaim("id").asString();//获取登录学生的id

        Leave leave1 = leaveMapper.selectByPrimaryKey(leave.getLeaveId());
        if (leave1.getStudentId() == studentId){//请假的学生id和登录用户id必须相等
            int result = leaveMapper.updateByPrimaryKeySelective(leave);
            if (result > 0) {
                LeaveOperationRecord record = new LeaveOperationRecord();
                record.setLeaveId(leave.getLeaveId());
                record.setOperationTime(new Date());
                record.setReasonsFailure("重新提交申请");
                int re = recordMapper.insertSelective(record);
                if (re > 0) {
                    return ResultUtil.success();
                } else {
                    throw new BusinessException(ExceptionEnum.ERROR);
                }
            } else {
                throw new BusinessException(ExceptionEnum.ERROR);
            }
        }else {
            throw new BusinessException(ExceptionEnum.IDENTITY_ERR);
        }

    }

}
